﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApplication1
{
    public sealed class EncryptUtils
    {
        #region Base64加密解密
        /// <summary>
        /// Base64加密
        /// </summary>
        /// <param name="input">需要加密的字符串</param>
        /// <returns></returns>
        public static string Base64Encrypt(string input)
        {
            return Base64Encrypt(input, new UTF8Encoding());
        }

        /// <summary>
        /// Base64加密
        /// </summary>
        /// <param name="input">需要加密的字符串</param>
        /// <param name="encode">字符编码</param>
        /// <returns></returns>
        public static string Base64Encrypt(string input, Encoding encode)
        {
            return Convert.ToBase64String(encode.GetBytes(input));
        }

        /// <summary>
        /// Base64解密
        /// </summary>
        /// <param name="input">需要解密的字符串</param>
        /// <returns></returns>
        public static string Base64Decrypt(string input)
        {
            return Base64Decrypt(input, new UTF8Encoding());
        }

        /// <summary>
        /// Base64解密
        /// </summary>
        /// <param name="input">需要解密的字符串</param>
        /// <param name="encode">字符的编码</param>
        /// <returns></returns>
        public static string Base64Decrypt(string input, Encoding encode)
        {
            return encode.GetString(Convert.FromBase64String(input));
        }
        #endregion


        public static string DESEncode(string str, string key = "12345678", string vector = "ABCDEFGH")
        {
            try
            {
                byte[] bkey = Encoding.UTF8.GetBytes(key);
                if (bkey.Length != 8)
                {
                    throw new Exception("DES加密出错：密钥字符串长度必须为8");
                }
                byte[] bvector = Encoding.UTF8.GetBytes(vector);
                if (bvector.Length != 8)
                {
                    throw new Exception("DES加密出错：初始化向量字符串长度必须为8");
                }
                byte[] data = Encoding.UTF8.GetBytes(str);
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                des.Key = bkey;
                des.IV = bvector;
                ICryptoTransform desCrypt = des.CreateEncryptor();//加密
                byte[] result = desCrypt.TransformFinalBlock(data, 0, data.Length);
                return BitConverter.ToString(result).Replace("-", "");
            }
            catch (Exception e)
            {
                throw new Exception("DES加密出错：" + e.Message);
            }
        }

        /// <summary>
        /// DES解密
        /// </summary>
        /// <param name="str">欲解密的明文</param>
        /// <param name="key">密钥（转成UTF-8码后的长度必须为8）</param>
        /// <param name="vector">向量（转成UTF-8码后的长度必须为8）</param>
        /// <returns>解密后的密文</returns>
        public static string DESDecode(string str, string key = "12345678", string vector = "ABCDEFGH")
        {
            try
            {
                byte[] bkey = Encoding.UTF8.GetBytes(key);
                if (bkey.Length != 8)
                {
                    throw new Exception("DES解密出错：密钥字符串长度必须为8");
                }
                byte[] bvector = Encoding.UTF8.GetBytes(vector);
                if (bvector.Length != 8)
                {
                    throw new Exception("DES解密出错：初始化向量字符串长度必须为8");
                }

                byte[] data = new byte[str.Length / 2];
                for (int i = 0; i < str.Length; i += 2)
                {
                    data[i / 2] = byte.Parse(str.Substring(i, 2), NumberStyles.HexNumber);
                }

                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                des.Key = bkey;
                des.IV = bvector;
                ICryptoTransform desCrypt = des.CreateDecryptor();//解密
                byte[] result = desCrypt.TransformFinalBlock(data, 0, data.Length);
                return Encoding.UTF8.GetString(result);
            }
            catch (Exception e)
            {
                return str;
                //throw new Exception("DES解密出错：" + e.Message);
            }
        }




        //#region DES加密解密
        ///// <summary>
        ///// DES加密
        ///// </summary>
        ///// <param name="data">加密数据</param>
        ///// <param name="key">8位字符的密钥字符串</param>
        ///// <param name="iv">8位字符的初始化向量字符串</param>
        ///// <returns></returns>
        //public static string DESEncrypt(string data, string key, string iv)
        //{
        //    byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(key);
        //    byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(iv);

        //    DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
        //    int i = cryptoProvider.KeySize;
        //    MemoryStream ms = new MemoryStream();
        //    CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateEncryptor(byKey, byIV), CryptoStreamMode.Write);

        //    StreamWriter sw = new StreamWriter(cst);
        //    sw.Write(data);
        //    sw.Flush();
        //    cst.FlushFinalBlock();
        //    sw.Flush();
        //    return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
        //}

        ///// <summary>
        ///// DES解密
        ///// </summary>
        ///// <param name="data">解密数据</param>
        ///// <param name="key">8位字符的密钥字符串(需要和加密时相同)</param>
        ///// <param name="iv">8位字符的初始化向量字符串(需要和加密时相同)</param>
        ///// <returns></returns>
        //public static string DESDecrypt(string data, string key, string iv)
        //{
        //    byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(key);
        //    byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(iv);

        //    byte[] byEnc;
        //    try
        //    {
        //        byEnc = Convert.FromBase64String(data);
        //    }
        //    catch
        //    {
        //        return data;
        //       // return null;
        //    }

        //    DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
        //    MemoryStream ms = new MemoryStream(byEnc);
        //    CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateDecryptor(byKey, byIV), CryptoStreamMode.Read);
        //    StreamReader sr = new StreamReader(cst);
        //    return sr.ReadToEnd();
        //}
        //#endregion

        #region MD5加密
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="input">需要加密的字符串</param>
        /// <returns></returns>
        public static string MD5Encrypt(string input)
        {
            return MD5Encrypt(input, new UTF8Encoding());
        }

        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="input">需要加密的字符串</param>
        /// <param name="encode">字符的编码</param>
        /// <returns></returns>
        public static string MD5Encrypt(string input, Encoding encode)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] t = md5.ComputeHash(encode.GetBytes(input));
            StringBuilder sb = new StringBuilder(32);
            for (int i = 0; i < t.Length; i++)
                sb.Append(t[i].ToString("x").PadLeft(2, '0'));
            return sb.ToString();
        }

        /// <summary>
        /// MD5对文件流加密
        /// </summary>
        /// <param name="sr"></param>
        /// <returns></returns>
        public static string MD5Encrypt(Stream stream)
        {
            MD5 md5serv = MD5CryptoServiceProvider.Create();
            byte[] buffer = md5serv.ComputeHash(stream);
            StringBuilder sb = new StringBuilder();
            foreach (byte var in buffer)
                sb.Append(var.ToString("x2"));
            return sb.ToString();
        }

        /// <summary>
        /// MD5加密(返回16位加密串)
        /// </summary>
        /// <param name="input"></param>
        /// <param name="encode"></param>
        /// <returns></returns>
        public static string MD5Encrypt16(string input, Encoding encode)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            string result = BitConverter.ToString(md5.ComputeHash(encode.GetBytes(input)), 4, 8);
            result = result.Replace("-", "");
            return result;
        }
        #endregion

        #region 3DES 加密解密

        public static string DES3Encrypt(string data, string key)
        {
            TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();

            DES.Key = ASCIIEncoding.ASCII.GetBytes(key);
            DES.Mode = CipherMode.CBC;
            DES.Padding = PaddingMode.PKCS7;

            ICryptoTransform DESEncrypt = DES.CreateEncryptor();

            byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(data);
            return Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));
        }

        public static string DES3Decrypt(string data, string key)
        {
            TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();

            DES.Key = ASCIIEncoding.ASCII.GetBytes(key);
            DES.Mode = CipherMode.CBC;
            DES.Padding = System.Security.Cryptography.PaddingMode.PKCS7;

            ICryptoTransform DESDecrypt = DES.CreateDecryptor();

            string result = "";
            try
            {
                byte[] Buffer = Convert.FromBase64String(data);
                result = ASCIIEncoding.ASCII.GetString(DESDecrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));
            }
            catch (Exception e)
            {

            }
            return result;
        }

        #endregion
    }
}
